package com.flyco.modules.oss.service.impl;

import cn.hutool.json.JSONUtil;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.PolicyConditions;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.flyco.common.util.CommonUtils;
import com.flyco.common.util.oss.OssBootUtil;
import com.flyco.modules.oss.entity.OSSFile;
import com.flyco.modules.oss.mapper.OSSFileMapper;
import com.flyco.modules.oss.service.IOSSFileService;
import com.flyco.modules.oss.vo.OssCallbackParam;
import com.flyco.modules.oss.vo.OssCallbackResult;
import com.flyco.modules.oss.vo.OssPolicyResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
@Slf4j
@Service("ossFileService")
public class OSSFileServiceImpl extends ServiceImpl<OSSFileMapper, OSSFile> implements IOSSFileService {

	@Value("${flyco.oss.callback}")
	private String callbackUrl;
	@Value("${flyco.oss.policy.expire}")
	private Integer expire;
	@Value("${flyco.oss.rootPath}")
	private String rootPath;

	@Override
	public void upload(MultipartFile multipartFile) throws IOException {
		String fileName = multipartFile.getOriginalFilename();
		fileName = CommonUtils.getFileName(fileName);
		OSSFile ossFile = new OSSFile();
		ossFile.setFileName(fileName);
		String url = OssBootUtil.upload(multipartFile,rootPath);
		ossFile.setUrl(url);
		this.save(ossFile);
	}

	@Override
	public void uploadByDir(MultipartFile multipartFile, String dir) throws IOException {
		String fileName = multipartFile.getOriginalFilename();
		fileName = CommonUtils.getFileName(fileName);
		OSSFile ossFile = new OSSFile();
		ossFile.setFileName(fileName);
		String url = OssBootUtil.upload(multipartFile,rootPath + "/" + dir);
		ossFile.setUrl(url);
		this.save(ossFile);
	}

	@Override
	public boolean delete(OSSFile ossFile) {
		try {
			this.removeById(ossFile.getId());
			OssBootUtil.deleteUrl(ossFile.getUrl());
		}
		catch (Exception ex) {
			return false;
		}
		return true;
	}

	/**
	 * 签名生成
	 */
	@Override
	public OssPolicyResult policy(String bizType) {
		OssPolicyResult result = new OssPolicyResult();
		// 存储目录
		String nowday = new SimpleDateFormat("yyyyMMdd").format(new Date());
		String dir = rootPath + "/cms/" + nowday + "/" +bizType;
		// 签名有效期
		long expireEndTime = System.currentTimeMillis() + expire * 1000;
		Date expiration = new Date(expireEndTime);
		// 文件大小
		long maxSize = 10 * 1024 * 1024;
		// 回调
		OssCallbackParam callback = new OssCallbackParam();
		callback.setCallbackUrl(callbackUrl);
		callback.setCallbackBody("filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}");
		callback.setCallbackBodyType("application/x-www-form-urlencoded");
		// 提交节点
		String action = "https://" + OssBootUtil.getBucketName() + "." + OssBootUtil.getEndPoint();
		try {
			PolicyConditions policyConds = new PolicyConditions();
			policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, maxSize);
			policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);
			String postPolicy = OssBootUtil.getOSSClient().generatePostPolicy(expiration, policyConds);
			byte[] binaryData = postPolicy.getBytes("utf-8");
			String policy = BinaryUtil.toBase64String(binaryData);
			String signature = OssBootUtil.getOSSClient().calculatePostSignature(postPolicy);
			String callbackData = BinaryUtil.toBase64String(JSONUtil.parse(callback).toString().getBytes("utf-8"));
			// 返回结果
			result.setAccessKeyId(OssBootUtil.getOSSClient().getCredentialsProvider().getCredentials().getAccessKeyId());
			result.setPolicy(policy);
			result.setSignature(signature);
			result.setDir(dir);
			result.setCallback(callbackData);
			result.setHost(action);
			result.setVisitHost("https://" + OssBootUtil.getStaticDomain());
		} catch (Exception e) {
			log.error("签名生成失败", e);
		}
		return result;
	}

	@Override
	public OssCallbackResult callback(HttpServletRequest request) {
		OssCallbackResult result= new OssCallbackResult();
		OSSFile ossFile = new OSSFile();
		ossFile.setType(request.getParameter("mimeType"));
		ossFile.setSize(Long.valueOf(request.getParameter("size")));
		ossFile.setWidth(Integer.parseInt(request.getParameter("width")));
		ossFile.setHeight(Integer.parseInt(request.getParameter("height")));
		String filename = request.getParameter("filename");
		ossFile.setFileName(filename);
		filename = "https://".concat(OssBootUtil.getStaticDomain()).concat("/").concat(filename);
		ossFile.setUrl(filename);
		result.setFilename(filename);
		result.setSize(String.valueOf(ossFile.getSize()));
		result.setMimeType(ossFile.getType());
		result.setWidth(ossFile.getWidth().toString());
		result.setHeight(ossFile.getHeight().toString());
		this.save(ossFile);
		return result;
	}

}
